home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld: Complete Mac Interactive
/
Macworld Complete Mac Interactive CD)(1994).iso
/
The Best of BMUG
/
Fonts
/
Font Utilities
/
BitFont 1.0.1
/
BitFont source
/
bitfont.c
next >
Wrap
C/C++ Source or Header
|
1991-12-01
|
55KB
|
2,299 lines
/* BitFont version 1.0.1 12/1/91
Author: Peter DiCamillo
Brown University Computing and Information Services
(401) 863-7582
Internet: Peter_DiCamillo@brown.edu
AppleLink: A0216
Compuserve: 73577,2036
America Online: PeterD11
BitFont and it's source are in the public domain, and may be freely
distributed.
Update History:
6/90 Initial version 1.0 for MacHack '90
12/1/91 Version 1.0.1: added support for format 6 subtable used in
TrueType 'cmap' table. The current TrueType version of
the Chicago font uses a format 6 subtable.
*/
#include <QuickDraw.h>
#include <Menus.h>
#include <Dialogs.h>
#include <Memory.h>
#include <SegLoad.h>
#include <Events.h>
#include <OSEvents.h>
#include <TextEdit.h>
#include <ToolUtils.h>
#include <Desk.h>
#include <Windows.h>
#include <Fonts.h>
#include <Files.h>
#include <Devices.h>
#include <Serial.h>
#include <Resources.h>
#include <Packages.h>
#include <Errors.h>
#include <StdIO.h>
#include <StdLib.h>
#include <String.h>
#include <Strings.h>
#define NMENUS 6 /* number of defined menus */
#define appleMenu 256
#define fileMenu 257
#define editMenu 258
#define fontMenu 259
#define sizeMenu 260
#define styleMenu 261
#define fileMSize 6 /* size of File menu */
typedef struct {
short image_left;
short image_right;
short image_top;
short image_bottom;
short pen_right;
char blank;
char missing;
} imageinfo;
#define ATMProcsStatusCode 0
#define ATMProcs3Version 3
typedef struct {
long version;
short (*fontAvailable)();
short (*showText)();
short (*xyshowText)();
} ATMProcs3;
typedef struct {
Fixed a, b, c, d, tx, ty;
} FixedMatrix;
typedef struct {
Fixed version;
Fixed fontRevision;
unsigned long checkSumAdjustment;
unsigned long magicNumber;
unsigned short flags;
unsigned short unitsPerEm;
long l1; /* start of created? */
long created;
long l2; /* start of modified? */
long modified;
short xMin;
short yMin;
short xMax;
short yMax;
unsigned short macStyle;
unsigned short lowestRecPPEM;
short fontDirectionHint;
short indexToLocFormat;
short glyphDataFormat;
} fontheader;
typedef struct {
Fixed version;
unsigned short numTables;
unsigned short searchRange;
unsigned short entrySelector;
unsigned short rangeShift;
} fontOffsetTable;
typedef struct {
unsigned long tag;
unsigned long checksum;
unsigned long offset;
unsigned long length;
} TableDirectory;
typedef struct {
unsigned short version;
unsigned short numTables;
} CharToGlyphHdr;
typedef struct {
unsigned short platformId;
unsigned short encodingId;
unsigned long offset;
} CharToGlyphDir;
typedef struct {
unsigned short format; /* 0 */
unsigned short length;
unsigned short revision;
unsigned char glyphIndexArray[256];
} CharToGlyphFmt0;
typedef struct {
unsigned short format; /* 6 */
unsigned short length;
unsigned short revision;
unsigned short firstCode;
unsigned short entryCount;
unsigned short glyphIndexArray[256]; /* could be any length */
} CharToGlyphFmt6;
/* function prototypes */
void macinit(void);
void definemenus(void);
void macend(void);
void hndmac(void);
void updevent(GrafPtr msgptr);
void drawgrid(char all);
void menu_upd(void);
void docommand(long mResult);
void appl_menu(void);
OSErr fontinit(void);
void fontend(void);
OSErr define_input(unsigned char *s, FMInput *r);
OSErr openrfile(void);
pascal Boolean onlyrsrc(FileParam *pb);
void getfref(void);
void closefile(void);
int sizescan(void);
void showextent(void);
void chars2text(void);
void analyse_char(unsigned char *addr, short charcode);
int getbit(unsigned char *p, short n);
int cvtleft(int i);
int cvtright(int i);
output_char(unsigned char *addr, short charcode);
void showerr(unsigned char *s);
void showmsg(unsigned char *s);
void ctralrt(short a);
void aboutdlg(void);
void fsizedlg(void);
void setfnum(DialogPtr dlgptr, short fs);
void showfrec(void);
pascal void frectext(WindowPtr dlgwindow, short item);
void showtext(WindowPtr dlgwindow, short item);
void showresrecord(unsigned char *s, WindowPtr dlgwindow);
void showfheader(unsigned char *s, WindowPtr dlgwindow);
unsigned long gettaboffset(Handle fh, unsigned long tag);
unsigned long getfmtoffset(CharToGlyphHdr *cmpp, short format);
void myDrawChar(short ch);
void dlgline(unsigned char *s);
void blankline(void);
int newrscfile(void);
int addfond(void);
int addfont(void);
void ctrwindow(GrafPtr wp);
void framedflt(DialogPtr dlgptr);
#define CHARSPERPAGE 2 /* characters/page for data file with cc */
#define NFNTID 1024 /* resource id to use for NFNT we create */
#define DELAYTICKS 6 /* controls speed of display when imaging NFNT data */
char done; /* true to exit program */
/* screen control rectangles */
/* variables for my window */
MenuHandle myMenus[NMENUS];
struct EventRecord myEvent;
char da_menu;
short bigscreen; /* screen at least 640 by 480 */
Rect screenRect; /* rectangle defining screen */
Rect dragRect; /* rectangle defining bounds for dragging */
Rect sizeRect; /* rectangle for resizing windows */
struct Point sfgpoint; /* standard file dialog locations */
struct Point sfppoint;
/* standard sizes for Size menu */
short sizelist[] = {7, 9, 10, 12, 14, 18, 24, 36, 48, 60, 72};
short fontsize = 9; /* initialized to default size */
FMInput dlginput; /* Font input record for show record dialog */
FMOutput dlgoutput; /* Font output record for show record dialog */
unsigned char dlgfname[256]; /* font name for show record dialog */
short dlgxpos, dlgypos; /* used to draw lines in dialog */
short myref; /* my resource manager reference number */
short resref; /* reference number of resource file to use */
short myfref; /* reference number for output file */
char fileflag; /* true if writing to a file */
unsigned char imagebuff[8196]; /* buffer for character bit image */
imageinfo scandata[257]; /* results from scanning font */
WindowRecord wRecord; /* window record for myWindow */
WindowPtr myWindow; /* handle to imaging display window */
GrafPort WritePort; /* Grafport for imaging */
GrafPtr WritePtr; /* pointer to GrafPort */
BitMap WriteMap; /* bitmap for GrafPort */
char newpage; /* counter for starting new pages */
char cc; /* generate carriage control */
char stdfont; /* font with standard character codes */
char atmfont; /* set if this font can be imaged by ATM */
char ttfont; /* set for a TrueType™ font ('sfnt') */
char atminit, atmavail; /* flags for opening ATM driver */
ATMProcs3 procs; /* ATM proc pointers */
/* variables for writing font resource file */
short currvol; /* current volume reference */
short rfile; /* file reference number */
unsigned char rscfname[64]; /* file name */
short rscvrefnum; /* volume reference for file */
Handle fondhandle; /* handles for resources */
Handle fonthandle;
char fontwindow; /* true = myWindow is FONT imaging */
main()
{
macinit(); /* initialize Mac */
cc = 0; /* set to one to generate carriage control */
stdfont = 1; /* set to zero if ASCII mappings do not apply */
myWindow = 0; /* no window yet */
atminit = 0; /* ATM not initialized */
done = 0;
while (!done) hndmac(); /* handle Mac events and I/O */
macend();
}
void macinit(void)
{
short i;
/* set-up general Macintosh environment */
MaxApplZone(); /* set-up for efficient storage use */
for (i=0; i < 4; i++) MoreMasters();
InitGraf(&qd.thePort);
FlushEvents(everyEvent, 0);
InitWindows();
InitFonts();
InitMenus();
InitDialogs(0L);
InitCursor();
TEInit();
/* set-up menus */
myref = resref = CurResFile();
da_menu = 0;
definemenus();
/* center alerts */
ctralrt(256);
ctralrt(260);
screenRect = qd.screenBits.bounds;
bigscreen = (((screenRect.bottom-screenRect.top) >= 480) &&
((screenRect.right-screenRect.left) >= 640));
/* calculate standard file dialog location*/
sfppoint.h = (screenRect.right-screenRect.left-304)/2;
sfgpoint.h = (screenRect.right-screenRect.left-348)/2;
if (bigscreen) {
sfppoint.v = (screenRect.bottom-screenRect.top-184)/3;
sfgpoint.v = (screenRect.bottom-screenRect.top-200)/3;
}
else {
sfppoint.v = (screenRect.bottom-screenRect.top-184)/2;
sfgpoint.v = (screenRect.bottom-screenRect.top-200)/2;
}
SetRect(&dragRect, 0, 24, screenRect.right-4, screenRect.bottom-4);
SetRect(&sizeRect, 50, 25, screenRect.right+1, screenRect.bottom+1);
fontwindow = 0;
}
void definemenus(void)
{
short i, msize;
Str255 itemname;
for (i=0; i < NMENUS; i++) {
myMenus[i] = GetMenu(256+i);
InsertMenu(myMenus[i], 0);
}
AddResMenu(myMenus[0], 'DRVR');
UseResFile(resref);
AddResMenu(myMenus[3], 'FONT');
UseResFile(myref);
for (i=0; i < sizeof(sizelist)/sizeof(short); i++) {
sprintf(itemname, "%d pt", sizelist[i]);
c2pstr(itemname);
AppendMenu(myMenus[4], itemname);
if (sizelist[i] == fontsize) CheckItem(myMenus[4], i+1, true);
}
AppendMenu(myMenus[4], "\P(-");
AppendMenu(myMenus[4], "\POther...");
/* initially select Geneva or first font */
msize = CountMItems(myMenus[3]);
if (msize > 0) {
CheckItem(myMenus[3], 1, true);
for (i=1; i <= msize; i++) {
GetItem(myMenus[3], i, itemname);
p2cstr(itemname);
if (strcmp(itemname, "Geneva") == 0) {
CheckItem(myMenus[3], 1, false);
CheckItem(myMenus[3], i, true);
break;
}
}
}
/* default is plain text */
CheckItem(myMenus[5], 1, true);
appl_menu();
}
void macend(void)
{
if (myWindow != 0) {
CloseWindow(myWindow);
myWindow = 0;
}
}
void hndmac(void)
{
OSErr rc;
short code;
GrafPtr gp;
unsigned short h, w;
long l;
WindowPtr whichWindow;
struct WindowRecord * fw;
char frontda;
rc = GetNextEvent(everyEvent, &myEvent);
if (rc == 0) /* FALSE from GNE */
switch(myEvent.what) {
case nullEvent:
fw = (WindowRecord *)FrontWindow();
frontda = fw->windowKind < 0;
if (frontda) {
if (!da_menu) {
da_menu = 1;
SetItem(myMenus[1], fileMSize, "\pClose");
appl_menu();
}
}
else {
if (da_menu) {
da_menu = 0;
SetItem(myMenus[1], fileMSize, "\pQuit");
appl_menu();
}
}
SystemTask(); /* run DAs, etc. */
break;
default:
return;
}
else switch(myEvent.what) { /* TRUE from GNE */
case mouseDown:
code = FindWindow(myEvent.where, &whichWindow);
switch (code) {
case inMenuBar:
menu_upd();
docommand(MenuSelect(myEvent.where));
break;
case inSysWindow:
SystemClick((EventRecord *)&myEvent, whichWindow);
break;
case inDrag:
if (whichWindow == FrontWindow())
DragWindow(whichWindow, myEvent.where, (Rect *)&dragRect);
else SelectWindow(whichWindow);
break;
case inGoAway:
break;
case inGrow:
if (whichWindow == FrontWindow()) {
GetPort(&gp);
SetPort((GrafPtr)whichWindow);
l = GrowWindow(whichWindow, myEvent.where, (Rect *)&sizeRect);
h = l >> 16;
w = l & 0x0000ffffL;
SizeWindow(whichWindow, w, h, 0x100);
SetPort(gp);
}
break;
case inContent:
if (whichWindow != FrontWindow()) {
SelectWindow(whichWindow);
break;
}
break;
case inZoomIn:
case inZoomOut:
if (TrackBox(whichWindow, myEvent.where, code)) {
if (((WindowPeek)whichWindow)->dataHandle == 0) break;
GetPort(&gp);
SetPort((GrafPtr)whichWindow);
EraseRect(&(((WindowRecord *)whichWindow)->port.portRect));
ZoomWindow(whichWindow, code, 0);
SetPort(gp);
}
break;
default:
break;
}
break;
case mouseUp:
break;
case keyDown:
case autoKey:
if (myEvent.modifiers & cmdKey) {
menu_upd();
docommand(MenuKey(myEvent.message & 0xff));
}
break;
case activateEvt:
break;
case updateEvt:
updevent((GrafPtr)myEvent.message);
break;
case app4Evt:
break;
default: break;
}
}
void updevent(GrafPtr msgptr)
{
GrafPtr gp;
GetPort(&gp);
SetPort(msgptr);
BeginUpdate(msgptr);
if ((msgptr = myWindow) && (myWindow != 0)) {
if (!fontwindow) drawgrid(1);
}
EndUpdate(msgptr);
SetPort(gp);
}
void drawgrid(char all)
{
short x1, x2, x3, x4;
x1 = 71;
x2 = 8;
x3 = 263;
x4 = 200;
if (!all) {
x1 -= 8;
x2 -= 8;
x3 -= 8;
x4 -= 8;
}
if (all) {
MoveTo(7, 7);
LineTo(264, 7);
LineTo(264, 264);
LineTo(7, 264);
LineTo(7, 7);
}
MoveTo(x1, x2);
LineTo(x1, x3);
MoveTo(x2, x4);
LineTo(x3, x4);
}
void menu_upd(void)
{
short i;
if (da_menu) {
for (i = 1; i < fileMSize; i++)
DisableItem(myMenus[1], i);
CheckItem(myMenus[1], fileMSize, 0);
}
else {
for (i = 1; i < fileMSize; i++)
EnableItem(myMenus[1], i);
CheckItem(myMenus[1], fileMSize, done << 8);
}
}
void docommand(long mResult)
{
register short theItem, theMenu;
unsigned char name[40];
WindowRecord * fw;
short i, msize, checked;
static char nullstr[1] = {0};
OSErr rc;
unsigned char errtext[256];
theMenu = mResult >> 16;
theItem = mResult & 0xff;
switch(theMenu) {
case appleMenu:
if (theItem == 2) break;
if (theItem == 1) {
aboutdlg();
break;
}
GetItem(myMenus[0], theItem, name);
OpenDeskAcc(name);
break;
case fileMenu:
switch (theItem) {
case 1:
rc = openrfile();
if (rc != 0) break;
HiliteMenu(0);
appl_menu();
ClearMenuBar();
for (i=0; i < NMENUS; i++) {
ReleaseResource((Handle)myMenus[i]);
}
definemenus();
return;
case 2:
case 3:
case 4:
case 5:
rc = fontinit();
if (rc != 0) break;
switch (theItem) {
case 2:
fileflag = 0;
showfrec();
break;
case 3:
rc = sizescan();
if (rc != 0) break;
showextent();
break;
case 4:
getfref();
if (myfref == 0) break;
fileflag = 1;
newpage = CHARSPERPAGE;
showfrec();
rc = sizescan();
if (rc == 0) chars2text();
closefile();
break;
case 5: /* create bitmap font */
rc = sizescan();
if (rc != 0) break;
rc = newrscfile();
if (rc != 0) break;
fondhandle = fonthandle = 0;
rc = addfont();
if (rc == 0) rc = addfond();
CloseResFile(rfile);
if (rc == 0) {
rc = ResError();
if (rc != 0) {
sprintf(errtext,
"Error %d closing resource to file", rc);
showerr(errtext);
}
}
if (rc != 0) {
FSDelete(rscfname, rscvrefnum);
}
SetVol(0L, currvol);
if (fondhandle != 0) {
DisposHandle(fondhandle);
}
if (fonthandle != 0) {
DisposHandle(fonthandle);
}
break;
default:
break;
}
fontend();
break;
case 6:
if (!da_menu) {
done ^= 1;
break;
}
else {
fw = (WindowRecord *)FrontWindow();
i = fw->windowKind;
if (i<0) CloseDeskAcc(i);
}
default: break;
}
break;
case editMenu:
SystemEdit(theItem-1);
break;
case fontMenu:
msize = CountMItems(myMenus[3]);
for (i=1; i <= msize; i++) {
CheckItem(myMenus[3], i, false);
}
CheckItem(myMenus[3], theItem, true);
break;
case sizeMenu:
msize = CountMItems(myMenus[4]);
if (theItem == msize) {
fsizedlg();
}
else {
fontsize = sizelist[theItem - 1];
}
checked = 0;
for (i=0; i < sizeof(sizelist)/sizeof(short); i++) {
CheckItem(myMenus[4], i+1, fontsize == sizelist[i]);
if (fontsize == sizelist[i]) checked = 1;
}
CheckItem(myMenus[4], msize, !checked);
break;
case styleMenu:
msize = CountMItems(myMenus[5]);
if (theItem == 1) {
CheckItem(myMenus[5], 1, true);
for (i=2; i <= msize; i++) {
CheckItem(myMenus[5], i, false);
}
}
else {
GetItemMark(myMenus[5], theItem, &i);
CheckItem(myMenus[5], theItem, i == noMark);
checked = noMark;
for (i=2; i <= msize; i++) {
GetItemMark(myMenus[5], i, &checked);
if (checked != noMark) break;
}
CheckItem(myMenus[5], 1, checked == noMark);
}
break;
default:
break;
}
HiliteMenu(0);
appl_menu();
}
void appl_menu(void) /* enable correct application menus */
{
static char last_da = 2; /* init to invalid value */
/* skip drawing menu if no changes from last time */
if (last_da == da_menu) return;
last_da = da_menu; /* save values for next time */
if (da_menu) {
EnableItem(myMenus[2], 0);
DisableItem(myMenus[3], 0);
DisableItem(myMenus[4], 0);
DisableItem(myMenus[5], 0);
}
else {
DisableItem(myMenus[2], 0);
EnableItem(myMenus[3], 0);
EnableItem(myMenus[4], 0);
EnableItem(myMenus[5], 0);
}
DrawMenuBar();
}
OSErr fontinit(void)
{
OSErr rc;
FMOutput *p;
long fontdef;
CntrlParam c;
rc = define_input(dlgfname, &dlginput);
if (rc != 0) {
showerr("Unable to define font input record");
return(rc);
}
UseResFile(resref);
p = FMSwapFont(&dlginput);
UseResFile(myref);
if (p == 0) {
showerr("Unable to define font output record");
return(1);
}
dlgoutput = *p;
rc = HandToHand(&(dlgoutput.fontHandle));
if (rc != 0) {
showerr("Not enough memory to copy font");
return(rc);
}
HLock(dlgoutput.fontHandle);
atmfont = ttfont = 0;
if (((*(FontRec **)(dlgoutput.fontHandle))->fontType
& 0x8000) == 0) {
ttfont = 1;
}
else { /* check for ATM font */
if (!atminit) {
atminit = 1;
atmavail = 0;
rc = OpenDriver("\P.ATM", &c.ioCRefNum);
if (rc == 0) {
c.csCode = ATMProcsStatusCode;
*(ATMProcs3**)c.csParam = &procs;
procs.version = ATMProcs3Version;
atmavail = (PBStatus((ParmBlkPtr)(&c), 0)) == 0;
}
}
if (atmavail) {
fontdef = dlginput.family << 16;
fontdef += dlginput.face;
rc = (*procs.fontAvailable)(fontdef);
atmfont = (rc == 1);
}
}
return(0);
}
void fontend(void)
{
DisposHandle(dlgoutput.fontHandle);
}
OSErr define_input(unsigned char *s, FMInput *r)
{
char checked;
short i, msize, markchar;
msize = CountMItems(myMenus[3]);
for (i=1; i <= msize; i++) {
GetItemMark(myMenus[3], i, &markchar);
if (markchar != noMark) {
checked = 1;
break;
}
}
if (!checked) return(1);
GetItem(myMenus[3], i, s);
UseResFile(resref);
GetFNum(s, &(r->family));
UseResFile(myref);
p2cstr(s);
r->size = fontsize;
r->face = 0;
GetItemMark(myMenus[5], 2, &markchar);
if (markchar != noMark) r->face |= bold;
GetItemMark(myMenus[5], 3, &markchar);
if (markchar != noMark) r->face |= italic;
GetItemMark(myMenus[5], 4, &markchar);
if (markchar != noMark) r->face |= underline;
GetItemMark(myMenus[5], 5, &markchar);
if (markchar != noMark) r->face |= outline;
GetItemMark(myMenus[5], 6, &markchar);
if (markchar != noMark) r->face |= shadow;
GetItemMark(myMenus[5], 7, &markchar);
if (markchar != noMark) r->face |= condense;
GetItemMark(myMenus[5], 8, &markchar);
if (markchar != noMark) r->face |= extend;
r->needBits = true;
r->device = 0;
(r->numer).v = (r->numer).h = (r->denom).v = (r->denom).h = 256;
return(0);
}
OSErr openrfile(void)
{
unsigned char *prompt;
FileFilterProcPtr fileFilter;
int numTypes;
SFTypeList typeList;
DlgHookProcPtr dlgHook;
SFReply reply;
pascal Boolean onlyrsrc();
prompt = 0;
dlgHook = 0;
fileFilter = onlyrsrc;
numTypes = -1;
SFGetFile(sfgpoint, prompt, fileFilter, numTypes,
&typeList,dlgHook,&reply);
if (reply.good == 0) return(1);
SetVol(0L, reply.vRefNum);
resref = OpenResFile(&reply.fName);
if (resref == 0) resref = myref;
UseResFile(myref);
return(0);
}
pascal Boolean onlyrsrc(FileParam *pb)
{
if (pb->ioFlRLgLen == 0L) return(true);
else return(0);
}
void getfref(void)
{
DlgHookProcPtr dlgHook;
SFReply reply;
OSErr rc;
myfref = 0;
dlgHook = 0;
SFPutFile(sfppoint, "\PSave font data in:", "\P", dlgHook, &reply);
if (reply.good == 0) return;
rc = FSDelete(&reply.fName, reply.vRefNum); /* delete existing file */
rc = Create(&reply.fName, reply.vRefNum, 'MPS ', 'TEXT');
rc = FSOpen(&reply.fName, reply.vRefNum, &myfref);
if (rc != 0) {
myfref = 0;
}
}
void closefile(void)
{
if (myfref != 0) {
FSClose(myfref);
myfref = 0;
}
}
int sizescan(void)
{
unsigned char *p;
short *owtab;
short firstchar, lastchar;
register short i;
unsigned short offset;
char foundmissing;
Rect pRect, destrect;
short vpixsize, hpixsize;
GrafPtr gp;
unsigned char *imageptr;
unsigned long mapoffset;
unsigned char *tp;
CharToGlyphHdr *cmpp;
unsigned long fmt_offset;
CharToGlyphFmt0 *fmt0p;
CharToGlyphFmt6 *fmt6p;
unsigned short startoffset, endoffset;
unsigned char errtext[128];
/* Define "missing" flag for each character using font resource */
if (ttfont) {
mapoffset = gettaboffset(dlgoutput.fontHandle, 'cmap');
if (mapoffset == 0) {
showerr("'cmap' table not found in 'sfnt' resource.");
return(1);
}
tp = *(unsigned char **)(dlgoutput.fontHandle);
tp += mapoffset;
cmpp = (CharToGlyphHdr *)tp;
fmt_offset = getfmtoffset(cmpp, 0);
if (fmt_offset == 0) {
showerr("Encoding id 0 not found in 'cmap' table.");
return(2);
}
tp += fmt_offset;
fmt0p = (CharToGlyphFmt0 *)tp;
foundmissing = 0;
switch (fmt0p->format) {
case 0:
for (i=0; i < 256; i++) {
scandata[i].missing = ((fmt0p->glyphIndexArray)[i] == 0);
if (scandata[i].missing) {
foundmissing = 1;
}
}
break;
case 6:
fmt6p = (CharToGlyphFmt6 *)tp;
startoffset = fmt6p->firstCode;
endoffset = startoffset + fmt6p->entryCount - 1;
for (i=0; i < 256; i++) {
if ((i < startoffset) || (i > endoffset)) {
scandata[i].missing = 1;
foundmissing = 1;
}
else {
scandata[i].missing =
((fmt6p->glyphIndexArray)[i-startoffset] == 0);
if (scandata[i].missing) {
foundmissing = 1;
}
}
}
break;
default:
sprintf(errtext,
"Sorry, 'cmap' subtable format %d is not supported.",
fmt0p->format);
showerr(errtext);
return(3);
break;
}
scandata[256].missing = (foundmissing == 0);
if (scandata[256].missing) {
showerr("Unable to draw missing character. Missing character will be blank");
}
}
else {
firstchar = (*(FontRec **)(dlgoutput.fontHandle))->firstChar;
lastchar = (*(FontRec **)(dlgoutput.fontHandle))->lastChar;
p = (unsigned char *)&(*(FontRec **)(dlgoutput.fontHandle))->owTLoc;
offset = (*(FontRec **)(dlgoutput.fontHandle))->owTLoc;
p += offset << 1;
owtab = (short *)p;
foundmissing = 0;
for (i=0; i < 256; i++) {
scandata[i].missing = 0;
if ((i < firstchar) || (i > lastchar)) {
scandata[i].missing = 1;
foundmissing = 1;
}
else {
scandata[i].missing = (owtab[i-firstchar] == -1);
if (scandata[i].missing) foundmissing = 1;
}
}
scandata[256].missing = (foundmissing == 0);
if (scandata[256].missing) {
showerr("Unable to draw missing character. Missing character will be blank");
}
}
/* define scan information for each character not missing, and for the
missing character */
/* create window to show what we are doing */
if (myWindow != 0) {
CloseWindow(myWindow);
myWindow = 0;
}
vpixsize = hpixsize = 272;
if (bigscreen) {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/3+9;
}
else {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/2+9;
}
pRect.left = (screenRect.right-screenRect.left-hpixsize)/2-1;
pRect.bottom = pRect.top+vpixsize;
pRect.right = pRect.left+hpixsize;
GetPort(&gp);
myWindow = NewWindow((Ptr)&wRecord, &pRect, "\pPass One: Character Sizes",
true, noGrowDocProc, (WindowPtr)-1L, false, 0L);
/* create image bitmap */
WriteMap.bounds.top = 0;
WriteMap.bounds.left = 0;
WriteMap.bounds.bottom = 256;
WriteMap.bounds.right = 256;
WriteMap.rowBytes = 32;
imageptr = imagebuff;
while ((Size)imageptr%4) imageptr++;
WriteMap.baseAddr = imageptr;
/* set-up corresponding GrafPort */
WritePtr = &WritePort; /* set-up WritePort */
OpenPort(WritePtr);
WritePort.portRect = WriteMap.bounds;
ClipRect(&WritePort.portRect);
SetPortBits(&WriteMap);
EraseRgn(WritePort.visRgn);
TextFont(dlginput.family);
TextFace(dlginput.face);
TextSize(dlginput.size);
destrect.top = destrect.left = 8;
destrect.bottom = destrect.right = 264;
SetPort(myWindow);
foundmissing = 0;
drawgrid(1);
/* entire font extent in element 256 */
scandata[256].image_left = scandata[256].image_top = 256;
scandata[256].image_right = scandata[256].image_bottom = -1;
scandata[256].pen_right = 0;
for (i=0; i < 256; i++) {
if (scandata[i].missing) {
if (foundmissing) continue;
else foundmissing = 1;
}
SetPort(WritePtr);
EraseRect(&WritePort.portRect);
MoveTo(64, 192);
UseResFile(resref);
myDrawChar(i);
analyse_char(WriteMap.baseAddr, i);
UseResFile(myref);
drawgrid(0);
SetPort(myWindow);
CopyBits(&WritePort.portBits, &(myWindow->portBits),
&WritePort.portRect, &destrect, srcCopy, 0L);
}
scandata[256].image_left = scandata[256].image_left - 64;
scandata[256].image_right = scandata[256].image_right - 64 + 1;
scandata[256].image_top = 192 - scandata[256].image_top;
scandata[256].image_bottom = 192 - scandata[256].image_bottom - 1;
scandata[256].pen_right = scandata[256].pen_right - 64;
SetPort(gp);
ClosePort(WritePtr);
CloseWindow(myWindow);
myWindow = 0;
return(0);
}
void showextent(void)
{
unsigned char s[256];
sprintf(s,
"Image rectange: left = %d, right = %d, bottom = %d, top = %d; maximum width (final pen position) = %d",
scandata[256].image_left, scandata[256].image_right,
scandata[256].image_bottom, scandata[256].image_top,
scandata[256].pen_right);
showmsg(s);
}
void chars2text(void)
{
Rect pRect, destrect;
short vpixsize, hpixsize;
GrafPtr gp;
unsigned char *imageptr;
char foundmissing;
unsigned char s[256];
register short i;
/* output information for each character not missing, and for the
missing character */
/* outut summary information for font */
blankline();
sprintf(s, "Extent information for entire font:");
dlgline(s);
sprintf(s, "Image rectange: left = %d, right = %d, bottom = %d, top = %d",
scandata[256].image_left, scandata[256].image_right,
scandata[256].image_bottom, scandata[256].image_top);
dlgline(s);
sprintf(s, "Width (final pen position) = %d", scandata[256].pen_right);
dlgline(s);
/* create window to show what we are doing */
if (myWindow != 0) {
CloseWindow(myWindow);
myWindow = 0;
}
vpixsize = hpixsize = 272;
if (bigscreen) {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/3+9;
}
else {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/2+9;
}
pRect.left = (screenRect.right-screenRect.left-hpixsize)/2-1;
pRect.bottom = pRect.top+vpixsize;
pRect.right = pRect.left+hpixsize;
GetPort(&gp);
myWindow = NewWindow((Ptr)&wRecord, &pRect, "\pPass Two: Bitmap Imaging",
true, noGrowDocProc, (WindowPtr)-1L, false, 0L);
/* create image bitmap */
WriteMap.bounds.top = 0;
WriteMap.bounds.left = 0;
WriteMap.bounds.bottom = 256;
WriteMap.bounds.right = 256;
WriteMap.rowBytes = 32;
imageptr = imagebuff;
while ((Size)imageptr%4) imageptr++;
WriteMap.baseAddr = imageptr;
/* set-up corresponding GrafPort */
WritePtr = &WritePort; /* set-up WritePort */
OpenPort(WritePtr);
WritePort.portRect = WriteMap.bounds;
ClipRect(&WritePort.portRect);
SetPortBits(&WriteMap);
EraseRgn(WritePort.visRgn);
TextFont(dlginput.family);
TextFace(dlginput.face);
TextSize(dlginput.size);
destrect.top = destrect.left = 8;
destrect.bottom = destrect.right = 264;
SetPort(myWindow);
foundmissing = 0;
drawgrid(1);
newpage = CHARSPERPAGE;
for (i=0; i < 256; i++) {
if (scandata[i].missing) {
if (foundmissing) continue;
else foundmissing = 1;
}
SetPort(WritePtr);
EraseRect(&WritePort.portRect);
MoveTo(64, 192);
UseResFile(resref);
myDrawChar(i);
output_char(WriteMap.baseAddr, i);
newpage++;
UseResFile(myref);
drawgrid(0);
SetPort(myWindow);
CopyBits(&WritePort.portBits, &(myWindow->portBits),
&WritePort.portRect, &destrect, srcCopy, 0L);
}
SetPort(gp);
ClosePort(WritePtr);
CloseWindow(myWindow);
myWindow = 0;
}
void analyse_char(unsigned char *addr, short charcode)
{
unsigned char *lineptr;
imageinfo *ifp, *ifps;
Point pt;
register short line, byte;
short leftbyte, rightbyte, bitpos;
lineptr = addr;
ifp = scandata + charcode;
ifps = scandata + 256; /* font summary info */
ifp->image_left = ifp->image_top = 256;
ifp->image_right = ifp->image_bottom = -1;
GetPen(&pt);
ifp->pen_right = pt.h - 64;
if (ifps->pen_right < pt.h) ifps->pen_right = pt.h;
ifp->blank = 1;
for (line = 0; line < 256; line++) {
leftbyte = -1;
for (byte = 0; byte < 32; byte++) {
if (lineptr[byte] != 0) {
leftbyte = byte;
break;
}
}
if (leftbyte >= 0) {
ifp->blank = 0;
if (line < ifp->image_top) ifp->image_top = line;
if (line > ifp->image_bottom) ifp->image_bottom = line;
if (line < ifps->image_top) ifps->image_top = line;
if (line > ifps->image_bottom) ifps->image_bottom = line;
bitpos = leftbyte*8 + cvtleft(lineptr[leftbyte]);
if (ifp->image_left > bitpos) ifp->image_left = bitpos;
if (ifps->image_left > bitpos) ifps->image_left = bitpos;
rightbyte = -1;
for (byte = 31; byte >= 0; byte--) {
if (lineptr[byte] != 0) {
rightbyte = byte;
break;
}
}
if (rightbyte >= 0) {
bitpos = rightbyte*8 + cvtright(lineptr[rightbyte]);
if (ifp->image_right < bitpos) ifp->image_right = bitpos;
if (ifps->image_right < bitpos) ifps->image_right = bitpos;
}
}
lineptr += 32;
}
if (ifp->blank == 0) {
ifp->image_left = ifp->image_left - 64;
ifp->image_right = ifp->image_right - 64 + 1;
ifp->image_top = 192 - ifp->image_top;
ifp->image_bottom = 192 - ifp->image_bottom - 1;
}
}
int getbit(unsigned char *p, short n)
{
register short byte, mask;
byte = n/8;
mask = 0x01 << (7-n%8);
if (p[byte] & mask) return('*');
else return('.');
}
int cvtleft(int i)
{
if (i & 0x80) return(0);
if (i & 0x40) return(1);
if (i & 0x20) return(2);
if (i & 0x10) return(3);
if (i & 0x08) return(4);
if (i & 0x04) return(5);
if (i & 0x02) return(6);
return(7);
}
int cvtright(int i)
{
if (i & 0x01) return(7);
if (i & 0x02) return(6);
if (i & 0x04) return(5);
if (i & 0x08) return(4);
if (i & 0x10) return(3);
if (i & 0x20) return(2);
if (i & 0x40) return(1);
return(0);
}
output_char(unsigned char *addr, short charcode)
{
unsigned char s[256];
imageinfo *ifp;
register short i, line, bit;
unsigned char *lineptr;
ifp = scandata + charcode;
blankline();
if (ifp->missing) {
sprintf(s, "Character: Missing character");
}
else {
if ((((charcode >= 0x20) && (charcode <= 0x7e)) ||
(charcode >= 0x80)) && stdfont) {
sprintf(s, "Character: x'%02x' (%c)", charcode, charcode);
}
else {
sprintf(s, "Character: x'%02x'", charcode);
}
}
if (ifp->blank) strcat(s, " [all blank]");
dlgline(s);
if (ifp->blank == 0) {
sprintf(s, "Image rectange: left = %d, right = %d, bottom = %d, top = %d",
ifp->image_left, ifp->image_right, ifp->image_bottom, ifp->image_top);
dlgline(s);
}
sprintf(s, "Width (final pen position) = %d", ifp->pen_right);
dlgline(s);
if (ifp->blank) return;
s[0] = s[1] = ' ';
if (cc) s[2] = 0xcc;
else s[2] = '+';
for (i = scandata[256].image_left; i < scandata[256].image_right; i++) {
if (cc) s[i+3-scandata[256].image_left] = 0xbd;
else s[i+3-scandata[256].image_left] = '-';
}
if (cc) s[i+3-scandata[256].image_left] = 0xde;
else s[i+3-scandata[256].image_left] = '+';
s[i+4-scandata[256].image_left] = '\0';
dlgline(s);
lineptr = addr;
lineptr += (192 - scandata[256].image_top)*32;
for (line = 192 - scandata[256].image_top;
line < 192 - scandata[256].image_bottom; line++) {
i = 191 - line;
if (i > 9) {
s[0] = i/10 + '0';
s[1] = i%10 + '0';
}
else if (i >= 0) {
s[0] = ' ';
s[1] = i + '0';
}
else {
s[0] = '-';
s[1] = (-i)%10 + '0';
}
if (cc) s[2] = 0xae;
else s[2] = '|';
for (bit = scandata[256].image_left+64; bit < scandata[256].image_right+64;
bit++) {
s[bit+3-scandata[256].image_left-64] = getbit(lineptr, bit);
}
if (cc) s[scandata[256].image_right-scandata[256].image_left+3] = 0xae;
else s[scandata[256].image_right-scandata[256].image_left+3] = '|';
s[scandata[256].image_right-scandata[256].image_left+4] = '\0';
dlgline(s);
lineptr += 32;
}
s[0] = s[1] = ' ';
if (cc) s[2] = 0xda;
else s[2] = '+';
for (i = scandata[256].image_left; i < scandata[256].image_right; i++) {
if (cc) s[i+3-scandata[256].image_left] = 0xbd;
else s[i+3-scandata[256].image_left] = '-';
}
if (cc) s[i+3-scandata[256].image_left] = 0x86;
else s[i+3-scandata[256].image_left] = '+';
s[i+4-scandata[256].image_left] = '\0';
dlgline(s);
s[0] = s[1] = s[2] = ' ';
for (i = scandata[256].image_left; i < scandata[256].image_right; i++) {
if (i < 0) s[i+3-scandata[256].image_left] = (-i)%10 + '0';
else s[i+3-scandata[256].image_left] = i%10 + '0';
}
s[i+3-scandata[256].image_left] = '\0';
dlgline(s);
if ((scandata[256].image_left < 0) ||
(scandata[256].image_right > 10)) {
s[0] = s[1] = s[2] = ' ';
for (i = scandata[256].image_left; i < scandata[256].image_right; i++) {
if (i < 0) s[i+3-scandata[256].image_left] = '-';
else if (i > 9) s[i+3-scandata[256].image_left] = i/10 + '0';
else s[i+3-scandata[256].image_left] = ' ';
}
s[i+3-scandata[256].image_left] = '\0';
dlgline(s);
}
}
void showerr(unsigned char *s)
{
static char nullstr[1] = {0};
c2pstr(s);
ParamText(s, nullstr, nullstr, nullstr);
p2cstr(s);
StopAlert(256, 0L);
ParamText(nullstr, nullstr, nullstr, nullstr);
}
void showmsg(unsigned char *s)
{
static char nullstr[1] = {0};
c2pstr(s);
ParamText(s, nullstr, nullstr, nullstr);
p2cstr(s);
NoteAlert(260, 0L);
ParamText(nullstr, nullstr, nullstr, nullstr);
}
void ctralrt(short a)
/* a is alert number */
{
Handle reshnd;
struct Rect * rptr;
short scrhsize, scrvsize;
short ahsize, avsize;
CouldAlert(a); /* read alert into memory and make unpurgeable */
reshnd = GetResource('ALRT', a);
if (reshnd == 0) return;
rptr = (struct Rect *)*reshnd;
scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
ahsize = rptr->right - rptr->left;
avsize = rptr->bottom - rptr->top;
rptr->top = (scrvsize-avsize)/3;
rptr->left = (scrhsize-ahsize)/2;
rptr->bottom = rptr->top + avsize;
rptr->right = rptr->left + ahsize;
}
void aboutdlg(void)
{
DialogPtr dlgptr;
short itemHit;
unsigned char **version;
static char nullstr[1] = {0};
dlgptr = GetNewDialog(257, (Ptr)0L, (WindowPtr)-1L);
if (bigscreen) ctrwindow(dlgptr);
version = GetResource('BTFT', 0);
if (version == 0L) {
DisposDialog(dlgptr);
return;
}
ParamText((*version), nullstr, nullstr, nullstr);
ShowWindow(dlgptr);
/* frame the default selection */
framedflt(dlgptr);
ModalDialog(0L, &itemHit);
DisposDialog(dlgptr);
ParamText(nullstr, nullstr, nullstr, nullstr);
}
void fsizedlg(void)
{
DialogPtr dlgptr;
short itemHit, lasthit;
short gtype;
Handle gitem;
Rect gbox;
short fs;
unsigned char result[256], newnum[10];
short i;
dlgptr = GetNewDialog(258, (Ptr)0L, (WindowPtr)-1L);
ctrwindow(dlgptr);
ShowWindow(dlgptr);
/* frame the default selection */
framedflt(dlgptr);
fs = fontsize;
setfnum(dlgptr, fs);
SelIText(dlgptr, 4, 0, 32767);
itemHit = 99;
lasthit = 99;
while (1) {
ModalDialog(0L, &itemHit);
if ((lasthit == 4) && (itemHit != 4)) {
GetDItem(dlgptr, 4, >ype, &gitem, &gbox);
GetIText(gitem, result);
p2cstr(result);
fs = atoi(result);
if (fs <= 0) fs = 9;
}
if (itemHit < 3) break;
switch(itemHit) {
case 4:
GetDItem(dlgptr, itemHit, >ype, &gitem, &gbox);
GetIText(gitem, result);
p2cstr(result);
i = 0;
while (result[i] != 0) {
if ((result[i] != 0x20) && ((result[i] < 0x30) ||
(result[i] > 0x39))) {
SysBeep(1);
break;
}
i++;
}
i = atoi(result) % 1000;
if (i == 0) {
newnum[0] = 0;
}
else {
sprintf(newnum, "%d", i);
}
if (strcmp(result, newnum) != 0) {
c2pstr(newnum);
SetIText(gitem, newnum);
}
break;
default:
break;
}
lasthit = itemHit;
}
DisposDialog(dlgptr);
if (itemHit == 1) fontsize = fs;
}
void setfnum(DialogPtr dlgptr, short fs)
{
short gtype;
Handle gitem;
Rect gbox;
unsigned char result[256], newnum[10];
GetDItem(dlgptr, 4, >ype, &gitem, &gbox);
GetIText(gitem, result);
p2cstr(result);
sprintf(newnum, "%d", fs);
if (strcmp(result, newnum) != 0) {
c2pstr(newnum);
SetIText(gitem, newnum);
}
}
void showfrec(void)
{
DialogPtr dlgptr;
short itemHit;
short gtype;
Handle gitem;
Rect mybox;
pascal void (*myitem) ();
pascal void frectext();
if (fileflag == 0) {
dlgptr = GetNewDialog(259, (Ptr)0L, (WindowPtr)-1L);
if (bigscreen) ctrwindow(dlgptr);
/* define routine to draw user item */
GetDItem(dlgptr, 2, >ype, &gitem, &mybox);
myitem = frectext;
SetDItem(dlgptr, 2, gtype, (Handle)myitem, &mybox);
ShowWindow(dlgptr);
/* frame the default selection */
framedflt(dlgptr);
ModalDialog(0L, &itemHit);
DisposDialog(dlgptr);
}
else {
showtext((WindowPtr)0L, 0);
}
}
pascal void frectext(WindowPtr dlgwindow, short item)
{
showtext(dlgwindow, item);
}
void showtext(WindowPtr dlgwindow, short item)
{
GrafPtr gp;
unsigned char s[256];
float d, n;
if (dlgwindow != 0) {
gp = (GrafPtr)item; /* avoid "not used" warning message */
GetPort(&gp);
SetPort(dlgwindow);
TextFont(3); /* Geneva */
TextSize(12); /* 9 and 12-point are always available */
dlgxpos = 5;
dlgypos = -4;
}
sprintf(s, "Font name = %s", dlgfname);
dlgline(s);
sprintf(s, "Font number = %d", dlginput.family);
dlgline(s);
if (dlgwindow != 0) {
TextFace(bold);
}
else {
blankline();
}
sprintf(s, "Font Output Record:");
dlgline(s);
if (dlgwindow != 0) {
TextFace(0);
}
sprintf(s, "Error number = %d", dlgoutput.errNum);
dlgline(s);
sprintf(s, "Bold factor = %d", dlgoutput.boldPixels);
dlgline(s);
sprintf(s, "Italic factor = %d", dlgoutput.italicPixels);
dlgline(s);
sprintf(s, "Underline offset = %d", dlgoutput.ulOffset);
dlgline(s);
sprintf(s, "Underline shadow = %d", dlgoutput.ulShadow);
dlgline(s);
sprintf(s, "Underline thickness = %d", dlgoutput.ulThick);
dlgline(s);
sprintf(s, "Shadow factor = %d", dlgoutput.shadowPixels);
dlgline(s);
sprintf(s, "Style width (extra) = %d", dlgoutput.extra);
dlgline(s);
sprintf(s, "Ascent = %d", dlgoutput.ascent);
dlgline(s);
sprintf(s, "Descent = %d", dlgoutput.descent);
dlgline(s);
sprintf(s, "Maximum width = %d", dlgoutput.widMax);
dlgline(s);
sprintf(s, "Leading = %d", dlgoutput.leading);
dlgline(s);
sprintf(s, "Styles to apply = %x", dlgoutput.unused);
dlgline(s);
n = dlgoutput.numer.h;
d = dlgoutput.denom.h;
sprintf(s, "Horiz. scaling = %f", n/d);
dlgline(s);
n = dlgoutput.numer.v;
d = dlgoutput.denom.v;
sprintf(s, "Vert. scaling = %f", n/d);
dlgline(s);
if (dlgwindow != 0) {
dlgxpos = 210;
dlgypos = -4;
}
sprintf(s, "Font size = %d", dlginput.size);
dlgline(s);
sprintf(s, "Styles = %x", dlginput.face);
dlgline(s);
if (dlgoutput.fontHandle == 0) {
if (dlgwindow != 0) {
SetPort(gp);
}
return;
}
if (ttfont) {
showfheader(s, dlgwindow);
}
else {
showresrecord(s, dlgwindow);
}
strcpy(s, "");
dlgline(s);
strcpy(s, "Imaging type: ");
if (ttfont) {
strcat(s, "TrueType™");
}
else if (atmfont) {
strcat (s, "ATM");
}
else {
strcat(s, "Bitmap");
}
dlgline(s);
if (dlgwindow != 0) {
SetPort(gp);
}
}
void showresrecord(unsigned char *s, WindowPtr dlgwindow)
{
if (dlgwindow != 0) {
TextFace(bold);
}
else {
blankline();
}
sprintf(s, "Font Resource Record:");
dlgline(s);
if (dlgwindow != 0) {
TextFace(0);
}
sprintf(s, "Font type = %x",
(unsigned short)(*(FontRec **)(dlgoutput.fontHandle))->fontType);
dlgline(s);
sprintf(s, "First character = %x",
(*(FontRec **)(dlgoutput.fontHandle))->firstChar);
dlgline(s);
sprintf(s, "Last character = %x",
(*(FontRec **)(dlgoutput.fontHandle))->lastChar);
dlgline(s);
sprintf(s, "Maximum width = %d",
(*(FontRec **)(dlgoutput.fontHandle))->widMax);
dlgline(s);
sprintf(s, "Negative max. kern = %d",
(*(FontRec **)(dlgoutput.fontHandle))->kernMax);
dlgline(s);
sprintf(s, "Negative descent = %d",
(*(FontRec **)(dlgoutput.fontHandle))->nDescent);
dlgline(s);
sprintf(s, "Rectangle width = %d",
(*(FontRec **)(dlgoutput.fontHandle))->fRectWidth);
dlgline(s);
sprintf(s, "Rectangle height = %d",
(*(FontRec **)(dlgoutput.fontHandle))->fRectHeight);
dlgline(s);
sprintf(s, "Offset table offset = %d",
(*(FontRec **)(dlgoutput.fontHandle))->owTLoc);
dlgline(s);
sprintf(s, "Ascent = %d",
(*(FontRec **)(dlgoutput.fontHandle))->ascent);
dlgline(s);
sprintf(s, "Descent = %d",
(*(FontRec **)(dlgoutput.fontHandle))->descent);
dlgline(s);
sprintf(s, "Leading = %d",
(*(FontRec **)(dlgoutput.fontHandle))->leading);
dlgline(s);
sprintf(s, "Row words = %d",
(*(FontRec **)(dlgoutput.fontHandle))->rowWords);
dlgline(s);
}
void showfheader(unsigned char *s, WindowPtr dlgwindow)
{
unsigned long hdroffset;
unsigned char *p;
fontheader *fhp;
unsigned char datestr[256];
unsigned char timestr[256];
float f;
hdroffset = gettaboffset(dlgoutput.fontHandle, 'head');
if (hdroffset == 0) return;
p = *(unsigned char **)(dlgoutput.fontHandle);
p += hdroffset;
fhp = (fontheader *)p;
if (dlgwindow != 0) {
TextFace(bold);
}
else {
blankline();
}
sprintf(s, "'sfnt' Font Header:");
dlgline(s);
if (dlgwindow != 0) {
TextFace(0);
}
f = (fhp->version & 0x0000ffff)/65536.0;
f += fhp->version >> 16;
sprintf(s, "Header version = %.2f", f);
dlgline(s);
f = (fhp->fontRevision & 0x0000ffff)/65536.0;
f += fhp->fontRevision >> 16;
sprintf(s, "Font revision = %.2f", f);
dlgline(s);
sprintf(s, "Flags = %x", fhp->flags);
dlgline(s);
sprintf(s, "Units per em = %d", fhp->unitsPerEm);
dlgline(s);
IUDateString(fhp->created, shortDate, datestr);
p2cstr(datestr);
IUTimeString(fhp->created, false, timestr);
p2cstr(timestr);
sprintf(s, "Created: %s %s", datestr, timestr);
dlgline(s);
IUDateString(fhp->modified, shortDate, datestr);
p2cstr(datestr);
IUTimeString(fhp->modified, false, timestr);
p2cstr(timestr);
sprintf(s, "Modified: %s %s", datestr, timestr);
dlgline(s);
sprintf(s, "xMin = %d", fhp->xMin);
dlgline(s);
sprintf(s, "yMin = %d", fhp->yMin);
dlgline(s);
sprintf(s, "xMax = %d", fhp->xMax);
dlgline(s);
sprintf(s, "yMax = %d", fhp->yMax);
dlgline(s);
sprintf(s, "Mac style = %x", fhp->macStyle);
dlgline(s);
sprintf(s, "Smallest readable size = %d", fhp->lowestRecPPEM);
dlgline(s);
sprintf(s, "Font direction hint = %d", fhp->fontDirectionHint);
dlgline(s);
}
unsigned long gettaboffset(Handle fh, unsigned long tag)
{
unsigned short i, tablecount;
unsigned char *p;
TableDirectory *tdp;
tablecount = (*(fontOffsetTable **)(fh))->numTables;
p = *(unsigned char **)(fh);
p += sizeof(fontOffsetTable);
tdp = (TableDirectory *)p;
for (i = 0; i < tablecount; i++) {
if (tdp->tag == tag) return(tdp->offset);
p += sizeof(TableDirectory);
tdp = (TableDirectory *)p;
}
return(0); /* 0 = tag not found */
}
unsigned long getfmtoffset(CharToGlyphHdr *cmpp, short format)
{
unsigned short i, tablecount;
unsigned char *p;
CharToGlyphDir *cgdp;
tablecount = cmpp->numTables;
p = (unsigned char *)cmpp;
p += sizeof(CharToGlyphHdr);
cgdp = (CharToGlyphDir *)p;
for (i = 0; i < tablecount; i++) {
if (cgdp->encodingId == format) return(cgdp->offset);
p += sizeof(CharToGlyphDir);
cgdp = (CharToGlyphDir *)p;
}
return(0); /* 0 = tag not found */
}
void myDrawChar(short ch)
{
struct {
unsigned char *text;
short length;
FixedMatrix *matrix;
} showparms;
unsigned char s[1];
FixedMatrix m;
if (atmfont) { /* could use DrawChar, but using ATM routine allows */
/* possible modifications to rotate, stretch, etc. */
s[0] = ch;
m.a = (Fixed) (dlginput.size*65536.0+0.5);
m.b = (Fixed) 0.;
m.c = (Fixed) 0.;
m.d = (Fixed) (-dlginput.size*65536.0+0.5);
m.tx = (Fixed) 0.;
m.ty = (Fixed) 0.;
showparms.text = s;
showparms.length = 1;
showparms.matrix = &m;
(*procs.showText)(showparms);
MoveTo(64 + (m.tx >> 16), 192);
}
else {
DrawChar(ch);
}
}
void dlgline(unsigned char *s)
{
long l;
static unsigned char nl[1] = {'\n'};
static unsigned char blank[1] = {0x20};
static unsigned char eject[1] = {'1'};
if (fileflag == 0) {
dlgypos += 14;
MoveTo(dlgxpos, dlgypos);
c2pstr(s);
DrawString(s);
}
else {
if (cc) {
if (newpage == CHARSPERPAGE) {
l = 1;
FSWrite(myfref, &l, eject);
newpage = 0;
}
else {
l = 1;
FSWrite(myfref, &l, blank);
}
}
l = strlen(s);
FSWrite(myfref, &l, s);
l = 1;
FSWrite(myfref, &l, nl);
}
}
void blankline(void)
{
long l;
static char nl[1] = {'\n'};
l = 1;
FSWrite(myfref, &l, nl);
}
int newrscfile(void) /* create new resource file for font resources */
{
DlgHookProcPtr dlgHook;
SFReply reply;
OSErr rc;
unsigned char errtext[276];
dlgHook = 0;
sprintf(errtext, "%s %d", dlgfname, dlginput.size);
c2pstr(errtext);
SFPutFile(sfppoint, "\PNew font file:",
errtext, dlgHook, &reply);
if (reply.good == 0) return(1);
memcpy(rscfname, &reply.fName, 64);
rscvrefnum = reply.vRefNum;
rc = FSDelete(rscfname, rscvrefnum); /* delete existing file */
rc = Create(rscfname, rscvrefnum, 'DMOV', 'FFIL');
if (rc != 0) {
sprintf(errtext, "Error %d creating output file.", rc);
showerr(errtext);
return(2);
}
GetVol(errtext, &currvol);
SetVol(0L, rscvrefnum);
CreateResFile(rscfname);
rfile = OpenResFile(rscfname);
if (rfile == -1) {
FSDelete(rscfname, rscvrefnum);
SetVol(0L, currvol);
sprintf(errtext, "Error %d opening resource file", ResError());
showerr(errtext);
return(3);
}
else {
UseResFile(myref);
return(0);
}
}
int addfond(void)
{
Size fondsize;
unsigned short resattr;
OSErr rc;
unsigned char errtext[256];
unsigned char *fondptr;
FamRec *fr;
FontAssoc *fa;
AsscEntry *ae;
short i;
char foundmissing;
/* get handle to data to write out */
fondsize = sizeof(FamRec) + sizeof(FontAssoc) + sizeof(AsscEntry);
fondhandle = NewHandle(fondsize);
if (fondhandle == 0) {
sprintf(errtext, "Out of memory allocating FOND resource");
showerr(errtext);
return(1);
}
/* initialize all fields to zero */
memset(*fondhandle, 0, fondsize);
fondptr = *fondhandle;
fr = (FamRec *)fondptr;
fr ->ffFlags = 0x8000; /* assume fixed-width */
foundmissing = 0;
for (i=0; i < 256; i++) {
if (scandata[i].missing) {
if (foundmissing) continue;
else foundmissing = 1;
}
if (scandata[i].pen_right != scandata[256].pen_right) {
fr->ffFlags = 0; /* reset if a different width */
break;
}
}
fr->ffFlags |= 0x6000; /* no fractional width table */
fr->ffFamID = dlginput.family;
fr->ffVersion = 2;
fondptr += sizeof(FamRec);
fa = (FontAssoc *)fondptr;
fa->numAssoc = 0; /* number of entries - 1 */
fondptr += sizeof(FontAssoc);
ae = (AsscEntry *)fondptr;
ae->fontSize = dlginput.size;
ae->fontStyle = dlginput.face;
ae->fontID = NFNTID;
c2pstr(dlgfname);
UseResFile(rfile);
AddResource(fondhandle, 'FOND', dlginput.family, dlgfname);
rc = ResError();
UseResFile(myref);
p2cstr(dlgfname);
if (rc) {
sprintf(errtext, "Error %d adding resource to file", rc);
showerr(errtext);
return(2);
}
resattr = GetResAttrs(fondhandle);
if (rc = ResError()) {
sprintf(errtext, "Error %d getting resource attributes", rc);
showerr(errtext);
return(3);
}
resattr |= resPurgeable;
SetResAttrs(fondhandle, resattr);
if (rc = ResError()) {
sprintf(errtext, "Error %d setting resource attributes", rc);
showerr(errtext);
return(4);
}
else {
return(0);
}
}
int addfont(void)
{
Size fntsize, imagesize;
unsigned short resattr;
OSErr rc;
unsigned char errtext[256];
unsigned char *fontptr, *owptr;
unsigned short *locptr;
short i, xpos, copyoffset;
short vpixsize, hpixsize;
char foundmissing, foundchar, fixedfont;
unsigned char firstchar, lastchar, missingchar;
unsigned short bitwidth, rowwords;
FontRec *fr;
GrafPtr gp;
Rect pRect, srcrect, destrect;
static unsigned long *Ticks = 0x16a;
unsigned long t;
/* get first char, last char., a missing char., fixed or proportional, */
/* maximum width, and sum of all image widths */
foundmissing = foundchar = 0;
fixedfont = 1;
bitwidth = 0;
for (i=0; i < 256; i++) {
if (scandata[i].missing) {
if (foundmissing) {
continue;
}
else {
foundmissing = 1;
missingchar = i;
}
}
if (scandata[i].pen_right != scandata[256].pen_right) {
fixedfont = 0; /* reset if a different width */
}
if (!scandata[i].blank) {
bitwidth += scandata[i].image_right - scandata[i].image_left;
}
if (scandata[i].missing) continue;
if (!foundchar) {
foundchar = 1;
firstchar = i;
}
lastchar = i;
}
/* get handle to data to write out */
fntsize = (bitwidth + 15) >> 4; /* row words */
rowwords = fntsize; /* save row words */
fntsize *= scandata[256].image_top - scandata[256].image_bottom; /* times row count */
imagesize = fntsize; /* save size in words */
fntsize <<= 1; /* convert to bytes */
fntsize += sizeof(FontRec); /* font record */
fntsize += (lastchar - firstchar + 3) << 2; /* loc. and ow tables */
fonthandle = NewHandle(fntsize);
if (fonthandle == 0) {
sprintf(errtext, "Out of memory allocating NFNT resource");
showerr(errtext);
return(1);
}
HLock(fonthandle);
/* initialize all fields to zero */
memset(*fonthandle, 0, fntsize);
fontptr = *fonthandle;
fr = (FontRec *)fontptr;
if (fixedfont) fr->fontType = 0xb000;
else fr->fontType = 0x9000;
fr->firstChar = firstchar;
fr->lastChar = lastchar;
fr->widMax = scandata[256].pen_right;
fr->kernMax = scandata[256].image_left;
if (fr->kernMax > 0) fr->kernMax = 0;
fr->nDescent = scandata[256].image_bottom;
fr->fRectWidth = scandata[256].image_right - scandata[256].image_left;
fr->fRectHeight = scandata[256].image_top - scandata[256].image_bottom;
fr->owTLoc = 4 + imagesize + (lastchar - firstchar + 3) + 1;
fr->ascent = scandata[256].image_top;
fr->descent = -(scandata[256].image_bottom);
fr->leading = dlgoutput.leading;
fr->leading *= dlgoutput.numer.v;
fr->leading += dlgoutput.denom.v >> 1;
fr->leading /= dlgoutput.denom.v;
fr->rowWords = rowwords;
/* done with font record part of resource; now draw the characters into the
bitImage table. The pen is positioned so that the non-blank characters
and the missing character are drawn in order adjacent to each other */
/* create window to show what we are doing */
if (myWindow != 0) {
CloseWindow(myWindow);
myWindow = 0;
}
vpixsize = fr->fRectHeight;
if (vpixsize > (screenRect.bottom - screenRect.top - 16))
vpixsize = screenRect.bottom - screenRect.top - 16;
hpixsize = screenRect.right - screenRect.left - 16;
if (hpixsize > bitwidth) hpixsize = bitwidth;
if (bigscreen) {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/3+9;
}
else {
pRect.top = (screenRect.bottom-screenRect.top-vpixsize)/2+9;
}
pRect.left = (screenRect.right-screenRect.left-hpixsize)/2-1;
pRect.bottom = pRect.top+vpixsize;
pRect.right = pRect.left+hpixsize;
GetPort(&gp);
myWindow = NewWindow((Ptr)&wRecord, &pRect, "\pPass Two: Character Imaging",
true, noGrowDocProc, (WindowPtr)-1L, false, 0L);
fontwindow = 1;
pRect.bottom = pRect.bottom - pRect.top; /* convert to local coordinates */
pRect.right = pRect.right - pRect.left;
pRect.top = pRect.left = 0;
/* define bitmap for characters */
WriteMap.bounds.top = 0;
WriteMap.bounds.bottom = fr->fRectHeight;
WriteMap.bounds.left = 0;
WriteMap.bounds.right = bitwidth;
WriteMap.rowBytes = fr->rowWords << 1;
fontptr += sizeof(FontRec);
WriteMap.baseAddr = fontptr;
/* set-up corresponding GrafPort */
WritePtr = &WritePort; /* set-up WritePort */
OpenPort(WritePtr);
WritePort.portRect = WriteMap.bounds;
ClipRect(&WritePort.portRect);
CopyRgn(WritePort.clipRgn, WritePort.visRgn);
SetPortBits(&WriteMap);
EraseRgn(WritePort.visRgn);
TextFont(dlginput.family);
TextFace(dlginput.face);
TextSize(dlginput.size);
srcrect.top = WriteMap.bounds.top;
srcrect.bottom = WriteMap.bounds.bottom;
destrect.top = pRect.top;
destrect.bottom = pRect.bottom;
while ((srcrect.bottom - srcrect.top) > (destrect.bottom - destrect.top)) {
srcrect.top++;
}
SetPort(myWindow);
xpos = 0;
copyoffset = 0;
t = *Ticks;
MoveTo(pRect.left, pRect.bottom - fr->descent);
LineTo(pRect.right, pRect.bottom - fr->descent);
for (i = 0; i < 257; i++) {
if (i != 256) {
if (scandata[i].missing || scandata[i].blank) continue;
}
SetPort(WritePtr);
if (i == 256) {
MoveTo(xpos-scandata[missingchar].image_left, fr->ascent);
}
else {
MoveTo(xpos-scandata[i].image_left, fr->ascent);
}
UseResFile(resref);
if (i == 256) myDrawChar(missingchar);
else myDrawChar(i);
UseResFile(myref);
SetPort(myWindow);
srcrect.left = xpos;
if (i == 256) {
xpos += scandata[missingchar].image_right
- scandata[missingchar].image_left;
}
else {
xpos += scandata[i].image_right - scandata[i].image_left;
}
srcrect.right = xpos;
destrect.left = srcrect.left - copyoffset;
destrect.right = destrect.left + srcrect.right - srcrect.left;
if (destrect.right > pRect.right) {
copyoffset = srcrect.left;
destrect.left = srcrect.left - copyoffset;
destrect.right = destrect.left + srcrect.right - srcrect.left;
EraseRect(&pRect);
MoveTo(pRect.left, pRect.bottom - fr->descent);
LineTo(pRect.right, pRect.bottom - fr->descent);
}
while ((*Ticks) < t);
CopyBits(&WritePort.portBits, &(myWindow->portBits),
&srcrect, &destrect, srcOr, 0L);
t = (*Ticks) + DELAYTICKS;
}
while ((*Ticks) < t);
SetPort(gp);
ClosePort(WritePtr);
CloseWindow(myWindow);
myWindow = 0;
fontwindow = 0;
/* loop to define the location table */
fontptr += imagesize << 1;
locptr = (unsigned short *)fontptr;
xpos = 0;
for (i = firstchar; i <= lastchar; i++) {
*locptr = xpos;
locptr++;
if (scandata[i].missing || scandata[i].blank) continue;
xpos += scandata[i].image_right - scandata[i].image_left;
}
*locptr = xpos;
locptr++;
xpos += scandata[missingchar].image_right - scandata[missingchar].image_left;
*locptr = xpos;
/* loop to define the offset/width table */
fontptr += (lastchar - firstchar + 3) << 1;
owptr = fontptr;
for (i = firstchar; i <= lastchar; i++) {
if (scandata[i].missing) {
*owptr = 0xff;
owptr++;
*owptr = 0xff;
owptr++;
}
else {
*owptr = scandata[i].image_left - fr->kernMax;
owptr++;
*owptr = scandata[i].pen_right;
owptr++;
}
}
*owptr = scandata[missingchar].image_left - fr->kernMax;
owptr++;
*owptr = scandata[i=missingchar].pen_right;
owptr++;
*owptr = 0xff;
owptr++;
*owptr = 0xff;
owptr++;
UseResFile(rfile);
AddResource(fonthandle, 'NFNT', NFNTID, "\P");
rc = ResError();
UseResFile(myref);
if (rc) {
sprintf(errtext, "Error %d adding resource to file", rc);
showerr(errtext);
return(2);
}
resattr = GetResAttrs(fonthandle);
if (rc = ResError()) {
sprintf(errtext, "Error %d getting resource attributes", rc);
showerr(errtext);
return(3);
}
resattr |= resPurgeable;
SetResAttrs(fonthandle, resattr);
if (rc = ResError()) {
sprintf(errtext, "Error %d setting resource attributes", rc);
showerr(errtext);
return(4);
}
else {
return(0);
}
}
void ctrwindow(GrafPtr wp)
{
short scrhsize, scrvsize;
short whsize, wvsize;
scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
whsize = wp->portRect.right-wp->portRect.left;
wvsize = wp->portRect.bottom - wp->portRect.top;
MoveWindow(wp, (scrhsize-whsize)/2, (scrvsize-wvsize)/3, 0);
}
void framedflt(DialogPtr dlgptr)
{
short gtype;
Handle gitem;
Rect gbox;
GrafPtr gp;
GetDItem(dlgptr, 1, >ype, &gitem, &gbox);
GetPort(&gp);
SetPort(dlgptr);
PenSize(3,3);
InsetRect(&gbox, -4, -4);
FrameRoundRect(&gbox, 16, 16);
SetPort(gp);
}